package fr.insee.solr.service.state;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.util.Collection;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.NestedNullException;
import org.apache.commons.beanutils.PropertyUtils;
import fr.insee.solr.model.annotation.SolrField;
import fr.insee.solr.service.impl.SolrInseeException;


public class StateSimpleMultivalued implements IState{

	@Override
	public Object getValue(Field f, SolrField a, Object o) throws SolrInseeException {
		try {
			Object iterable = PropertyUtils.getProperty(o, f.getName());
			if(iterable != null){
				if(iterable instanceof Iterable<?>){
					return iterable;
				} else throw new SolrInseeException(ERROR_NO_ITERABLE_TYPE + a.fieldName());
			} else return null;
		} catch (IllegalAccessException | InvocationTargetException	| NoSuchMethodException e) {
			throw new SolrInseeException(ERROR_NO_SUCH_FIELD + a.fieldName(),e);
		} catch(NestedNullException e){
			return null;
		}
		
	}

	@Override
	public void fillValue(Object bean, Field f, SolrField a, Object solrValue) throws SolrInseeException {
		try {	
			Class<?> typeListe = PropertyUtils.getPropertyType(bean, f.getName());
			Collection<Object> collection = StateUtils.createCollection(typeListe);
			
			if(solrValue != null && solrValue instanceof Collection){
				ParameterizedType listeType = (ParameterizedType) f.getGenericType();
		        Class<?> classGeneric = (Class<?>) listeType.getActualTypeArguments()[0];
				for(Object o : ((Collection<?>)solrValue)){
					Object value = ConvertUtils.convert(o, classGeneric);
					
					if(o != null){
						collection.add(value);
					}
				}
			}
			
			if(collection != null) PropertyUtils.setProperty(bean, f.getName(), collection);
		} catch (IllegalAccessException | InvocationTargetException	| NoSuchMethodException e) {
			throw new SolrInseeException(ERROR_FILL_FIELD + f.getName(),e);
		}
		
	}

}
